#include "stdlib.hpp"
#include <purewell/user.hpp>

#ifndef WIN32
#	include <pwd.h>
#	include <grp.h>
#endif//!WIN32

namespace purewell
{

enum
{
	__PW_USER_DEFAULT_BUFFER_SIZE = (1024*2),
	__PW_GROUP_DEFAULT_BUFFER_SIZE = (1024*4),
};

PWUser::PWUser() : m_uid(0), m_gid(0)
{
}

PWUser::~PWUser()
{
}

bool
PWUser::getUser(uid_t uid)
{
#ifndef WIN32
	struct passwd pwd;
	struct passwd* rpwd;
	char buf[__PW_USER_DEFAULT_BUFFER_SIZE];
	if ( 0 != getpwuid_r(uid, &pwd, buf, sizeof(buf), &rpwd) )
	{
		return false;
	}

	m_id = pwd.pw_name;
	m_password = pwd.pw_passwd;
	m_uid = pwd.pw_uid;
	m_gid = pwd.pw_gid;
	m_name = pwd.pw_gecos;
	m_homedir = pwd.pw_dir;
	m_shell = pwd.pw_shell;

	return true;
#else
	__PWERRNO_NOIMPL();
	return false;
#endif
}

bool
PWUser::getUser(const char* id)
{
#ifndef WIN32
	struct passwd pwd;
	struct passwd* rpwd;
	char buf[__PW_USER_DEFAULT_BUFFER_SIZE];
	if ( 0 != getpwnam_r(id, &pwd, buf, sizeof(buf), &rpwd) )
	{
		return false;
	}

	m_id = pwd.pw_name;
	m_password = pwd.pw_passwd;
	m_uid = pwd.pw_uid;
	m_gid = pwd.pw_gid;
	m_name = pwd.pw_gecos;
	m_homedir = pwd.pw_dir;
	m_shell = pwd.pw_shell;

	return true;
#else
	__PWERRNO_NOIMPL();
	return false;
#endif
}

PWGroup::PWGroup() : m_gid(0)
{
}

PWGroup::~PWGroup()
{
}

bool
PWGroup::getGroup(gid_t gid)
{
#ifndef WIN32
	struct group grp;
	struct group* rgrp;
	char buf[__PW_GROUP_DEFAULT_BUFFER_SIZE];
	if ( 0 != getgrgid_r(gid, &grp, buf, sizeof(buf), &rgrp) )
	{
		return false;
	}

	m_id = grp.gr_name;
	m_password = grp.gr_passwd;
	m_gid = grp.gr_gid;
	m_users.clear();
	char** ptr(grp.gr_mem);
	if ( NULL != ptr )
	{
		while ( NULL != *ptr )
		{
			m_users.push_back(*ptr);
			++ptr;
		}
	}

	return true;
#else
	__PWERRNO_NOIMPL();
	return false;
#endif
}

bool
PWGroup::getGroup(const char* id)
{
#ifndef WIN32
	struct group grp;
	struct group* rgrp;
	char buf[__PW_GROUP_DEFAULT_BUFFER_SIZE];
	if ( 0 != getgrnam_r(id, &grp, buf, sizeof(buf), &rgrp) )
	{
		return false;
	}

	m_id = grp.gr_name;
	m_password = grp.gr_passwd;
	m_gid = grp.gr_gid;
	m_users.clear();
	char** ptr(grp.gr_mem);
	if ( NULL != ptr )
	{
		while ( NULL != *ptr )
		{
			m_users.push_back(*ptr);
			++ptr;
		}
	}

	return true;
#else
	__PWERRNO_NOIMPL();
	return false;
#endif
}

};//namespace purewell

